home *** CD-ROM | disk | FTP | other *** search
- /*
- Edit Extender Desk Accessory
- for MacTutor Magazine
- June 1, 1988
- by Joel McNamara, Satori Software
- */
-
- /* the required stuff... */
- #include "EventMgr.h"
- #include "MenuMgr.h"
- #include "MemoryMgr.h"
- #include "FontMgr.h"
- #include "FileMgr.h"
- #include "DeviceMgr.h"
- #include "DialogMgr.h"
- #include "IntlPkg.h"
- #include "StdFilePkg.h"
-
- /* the globals... */
- int ALREADY_OPEN = 0;
- int CONDITION = 0;
- int RUNCODE = 0;
- DCtlPtr DCE;
- GrafPtr SAVEPORT;
- MenuHandle THE_MENUHANDLE;
-
- /* the constants... */
-
- /* this routine returns the correct resource number for the driver */
- #define RsrcID(id) (0xC000 + (~DCE->dCtlRefNum << 5) + id)
-
- /* the dialogs */
- #define AboutDLOG 0
- #define CountsDLOG 1
- #define MessageDLOG 2
-
- /* counts DITL items */
- #define CharItem 2
- #define WordsItem 3
- #define SentenceItem 4
- #define ParagraphItem 5
-
- /* the fake window */
- #define FakeWIND 0
-
- /* run code commands */
- #define UpperCaseCOND 1
- #define LowerCaseCOND 2
- #define ReverseCaseCOND 3
- #define CapitalizeCOND 4
- #define CountsCOND 5
- #define TextCOND 6
- #define DateCOND 7
- #define TimeCOND 8
-
- /* STR# error messages */
- #define ListSTR 0
- #define MemoryMSG 1
- #define GenericMSG 2
- #define CreateMSG 3
- #define OpenMSG 4
- #define WriteMSG 5
- #define SelectMSG 6
-
- /* menu items */
- #define AboutITEM 1
- #define UpperITEM 3
- #define LowerITEM 4
- #define ReverseITEM 5
- #define CapitalITEM 6
- #define DateITEM 8
- #define TimeITEM 9
- #define CountsITEM 11
- #define TextITEM 13
- #define QuitITEM 15
-
- /* DA messages */
- #define OpenMessage 0
- #define ControlMessage 2
- #define CloseMessage 4
-
- /* let's start... */
- main(controlParam, dControl, message)
- cntrlParam *controlParam;
- DCtlPtr dControl;
- short message;
- {
- EvQEl tempQElement;
-
- if ((dControl->dCtlStorage) == 0) {
- SysBeep(5);
- if (message == OpenMessage) {
- SysBeep(5);
- Display(MemoryMSG);
- CloseDriver(dControl->dCtlRefNum);
- }
- return(0);
- }
-
- DCE = dControl;
- switch (message) {
- case OpenMessage:
- DoOpen();
- break;
-
- case ControlMessage:
- switch (controlParam->csCode) {
- /* who needs to be in control */
- case accRun:
- if ((RUNCODE != 0) && (OSEventAvail(keyDownMask,
- &tempQElement) == 0))
- DoRuncode(RUNCODE);
- break;
-
- case accMenu:
- DoMenu(controlParam->csParam[1]);
- break;
-
- case goodBye:
- DoGoodBye();
- break;
- }
- break;
-
- case CloseMessage:
- DoClose();
- break;
- }
- return(0);
- }
-
- /* open the DA */
- DoOpen()
- {
- DCE->dCtlFlags |= dNeedLock|dNeedGoodBye|dCtlEnable|dNeedTime;
- DCE->dCtlDelay = 15;
- DCE->dCtlMenu = RsrcID(0);
- if (ALREADY_OPEN)
- return;
-
- RUNCODE = 0;
- ALREADY_OPEN = 1;
- THE_MENUHANDLE = GetMenu( DCE->dCtlMenu);
- (*THE_MENUHANDLE)->menuID = DCE->dCtlMenu;
- InsertMenu(THE_MENUHANDLE,0);
- DrawMenuBar();
- }
-
- /* handle any menu items */
- DoMenu(theItem)
- int theItem;
- {
- switch (theItem)
- {
- case AboutITEM:
- DoAbout();
- break;
-
- case UpperITEM:
- DoCopy();
- CONDITION = UpperCaseCOND;
- break;
-
- case LowerITEM:
- DoCopy();
- CONDITION = LowerCaseCOND;
- break;
-
- case ReverseITEM:
- DoCopy();
- CONDITION = ReverseCaseCOND;
- break;
-
- case CapitalITEM:
- DoCopy();
- CONDITION = CapitalizeCOND;
- break;
-
- case DateITEM:
- SetRuncode();
- CONDITION = DateCOND;
- break;
-
- case TimeITEM:
- SetRuncode();
- CONDITION = TimeCOND;
- break;
-
- case CountsITEM:
- DoCopy();
- CONDITION = CountsCOND;
- break;
-
- case TextITEM:
- DoCopy();
- CONDITION = TextCOND;
- break;
-
- case QuitITEM:
- DoClose();
- break;
-
- default:
- break;
- }
- HiliteMenu(0);
- }
-
- /* about us */
- DoAbout()
- {
- DialogPtr theDialog;
- int dummy;
-
- theDialog = GetNewDialog(RsrcID(AboutDLOG),0,-1);
- ModalDialog(0, &dummy);
- DisposDialog(theDialog);
- }
-
- /* close everything up */
- DoClose()
- {
- DeleteMenu(DCE->dCtlMenu);
- DisposeMenu(THE_MENUHANDLE);
- ALREADY_OPEN = 0;
- DCE->dCtlMenu = 0;
- DCE->dCtlWindow = 0;
- DrawMenuBar();
- }
-
- /* good bye... */
- DoGoodBye()
- {
- DCE->dCtlMenu = 0;
- DCE->dCtlWindow = 0;
- }
-
- /* do a control c */
- DoCopy()
- {
- struct keys{
- long charCode;
- long modifiers;
- } *keysPtr;
- long len;
-
- GetPort(&SAVEPORT);
- len = ZeroScrap();
- keysPtr = (struct keys*)0x174;
- keysPtr->charCode = 0x00000000;
- keysPtr->modifiers = 0x00008000;
- PostEvent(3,67);
- keysPtr->charCode = 0x00000000;
- keysPtr->modifiers = 0x00000000;
- RUNCODE = 1;
- }
-
- /* get the DA's attention */
- SetRuncode()
- {
- RUNCODE = 1;
- }
-
- /* handle any run codes */
- DoRuncode(myRunCode)
- short myRunCode;
- {
- switch (myRunCode)
- {
- case 1: /* bring up the dummy window */
- DCE->dCtlWindow = GetNewWindow(RsrcID(FakeWIND),0,-1);
- ((WindowPeek)(DCE->dCtlWindow))->windowKind = DCE->dCtlRefNum;
- SetPort(DCE->dCtlWindow);
- RUNCODE = 2;
- break;
-
- case 2: /* do a paste event */
- PostPaste();
- RUNCODE = 3;
- break;
-
- case 3: /* now deal with our commands */
- DoText();
- break;
-
- default:
- break;
- }
- }
-
- /* here's where we do our edit commands */
- DoText()
- {
- long len;
- long myOffset;
- long loop;
- long temp;
- long theSecs;
-
- Handle myHandle;
- Handle newHandle;
- Handle theHandle;
-
- Rect itemRect;
-
- int sentences;
- int paragraphs;
- int words;
- int chars;
- int itemType;
- int tempInt;
-
- char myChar;
- char prevChar;
-
- DialogPtr theDialog;
- Ptr myPtr;
-
- Str255 numStr;
- Str255 timeStr;
-
-
- RUNCODE = 0;
- myHandle = NewHandle(0);
-
- len = GetScrap(myHandle,'TEXT',&myOffset);
- if ((len <= 0) && (CONDITION <= CapitalizeCOND))
- /* nothing's in the scrap */
- {
- SysBeep(5);
- Display(SelectMSG);
- DisposeWindow(DCE->dCtlWindow);
- DCE->dCtlWindow = 0;
- SetPort(SAVEPORT);
- }
- else
- {
- if (CONDITION < CountsCOND)
- /* do we need a handle for manipulation? */
- newHandle = NewHandle(GetHandleSize(myHandle));
-
- switch (CONDITION)
- {
- /* the upper routine */
- case UpperCaseCOND:
- for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++)
- *(((char *)(*newHandle)) + loop) = toupper(*((char *)((long)(*myHandle) + loop)));
- break;
-
- /* the lower case routine */
- case LowerCaseCOND:
- for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++)
- *((char *)((long)(*newHandle) + loop)) = tolower(*((char *)((long)(*myHandle) + loop)));
- break;
-
- /* the reverse case routine */
- case ReverseCaseCOND:
- for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++) {
- if (isupper(*((char *)((long)(*myHandle) + loop))))
- *((char *)((long)(*newHandle) + loop)) = tolower(*((char *)((long)(*myHandle) + loop)));
- else
- if (islower(*((char *)((long)(*myHandle) + (long)loop))))
- *((char *)((long)(*newHandle) + loop)) = toupper(*((char *)((long)(*myHandle) + loop)));
- else
- *((char *)((long)(*newHandle) + loop)) = *((char *)((long)(*myHandle) + loop));
- }
- break;
-
- /* the capitalization routine */
- case CapitalizeCOND:
- prevChar = (char)'x';
- for (loop = 0; loop <= (GetHandleSize(myHandle)); loop++)
- {
- if (loop == 0)
- {
- *((char *)((long)(*newHandle) + loop)) = toupper(*((char *)((long)(*myHandle) + loop)));
- prevChar = *((char *)((long)(*newHandle) + loop));
- }
- else
- {
- if ((prevChar == ' ') || (prevChar == '\r') ||
- (prevChar == '\t'))
- *((char *)((long)(*newHandle) + loop)) = toupper(*((char *)((long)(*myHandle) + loop)));
- else
- *((char *)((long)(*newHandle) + loop)) = *((char *)((long)(*myHandle) + loop));
- prevChar = *((char *)((long)(*newHandle) + loop));
- }
- }
- break;
-
- /* a simplistic wc */
- case CountsCOND:
- chars = sentences = paragraphs = words = 0;
-
- myPtr = *myHandle;
- for (temp = 0; temp <= len; temp++)
- {
- myChar = *((char *)((long)myPtr + temp));
- chars++;
-
- if (myChar == '\r')
- paragraphs++;
-
- if (myChar == '.' || myChar == '!' || myChar == '?')
- sentences++;
-
- if (myChar == ' ' || myChar == '\t' || myChar == '\r')
- words++;
- }
-
- InitCursor();
- theDialog = GetNewDialog(RsrcID(CountsDLOG),0,-1);
- SetPort(theDialog);
-
- NumToString(chars - paragraphs,numStr);
- GetDItem(theDialog,CharItem,&itemType,&theHandle,&itemRect);
- SetIText(theHandle,numStr);
-
- NumToString(words,numStr);
- GetDItem(theDialog,WordsItem,&itemType,&theHandle,&itemRect);
- SetIText(theHandle,numStr);
-
- NumToString(sentences,numStr);
- GetDItem(theDialog,SentenceItem,&itemType,&theHandle,&itemRect);
- SetIText(theHandle,numStr);
-
- NumToString(paragraphs,numStr);
- GetDItem(theDialog,ParagraphItem,&itemType,&theHandle,&itemRect);
- SetIText(theHandle,numStr);
-
- ModalDialog(0,&tempInt);
- CloseDialog(theDialog);
- break;
-
- /* text to save condition */
- case TextCOND:
- Extract(myHandle);
- break;
-
- /* display date condition */
- case DateCOND:
- GetDateTime(&theSecs);
- IUDateString(theSecs,longDate,&timeStr);
- PtoCstr(timeStr);
- ZeroScrap();
- PutScrap(strlen(timeStr),'TEXT',&timeStr);
- PostPaste();
- break;
-
- /* display time condition */
- case TimeCOND:
- GetDateTime(&theSecs);
- IUTimeString(theSecs,TRUE,&timeStr);
- PtoCstr(timeStr);
- ZeroScrap();
- PutScrap(strlen(timeStr),'TEXT',&timeStr);
- PostPaste();
- break;
-
- default:
- break;
- }
-
- DisposeWindow(DCE->dCtlWindow);
- DCE->dCtlWindow = 0;
- SetPort(SAVEPORT);
-
- if (CONDITION < CountsCOND)
- /* then we need to paste in the new stuff */
- {
- ZeroScrap();
- PutScrap(GetHandleSize(myHandle),'TEXT',*newHandle);
- DisposHandle(newHandle);
- PostPaste();
- }
- }
- DisposHandle(myHandle);
- CONDITION = 0;
- }
-
- /* do a paste event */
- PostPaste()
- {
- struct keys{
- long charCode;
- long modifiers;
- } *keysPtr;
-
- keysPtr = (struct keys*)0x174;
- keysPtr->charCode = 0x00000000;
- keysPtr->modifiers = 0x00008000;
- PostEvent(3,86);
- keysPtr->charCode = 0x00000000;
- keysPtr->modifiers = 0x00000000;
- }
-
- /* error message display */
- Display(theIndex)
- int theIndex;
- {
- DialogPtr theDialog;
- int dummy;
- Str255 theMessage;
-
- GetIndString(&theMessage,RsrcID(ListSTR),theIndex);
- InitCursor();
- theDialog = GetNewDialog(RsrcID(MessageDLOG),0,-1);
- ParamText(theMessage,"\p","\p","\p");
- ModalDialog(0,&dummy);
- DisposDialog(theDialog);
- }
-
- /* save selected text to a file */
- Extract(myHandle)
- Handle myHandle;
- {
- SFReply myReply;
- Point myLoc;
- int errCode, refNum;
- long theCount;
-
- myLoc.v = 90;
- myLoc.h = 90;
-
- HLock(myHandle);
- SFPutFile(myLoc,"\pSave selected text to:","\pUntitled",0L,&myReply);
-
- if (myReply.good)
- {
- errCode = Create(myReply.fName,myReply.vRefNum,'EDIT','TEXT');
- if (errCode != noErr);
- {
- if (errCode == dupFNErr) {
- FSDelete(myReply.fName,myReply.vRefNum);
- errCode = Create(myReply.fName,myReply.vRefNum,'EDIT','TEXT');
- }
- else if (errCode != noErr) {
- Display(CreateMSG);
- HUnlock(myHandle);
- return;
- }
- }
-
- if (FSOpen(myReply.fName,myReply.vRefNum,&refNum) != noErr) {
- Display(OpenMSG);
- FSClose(refNum);
- HUnlock(myHandle);
- return;
- }
-
- theCount = GetHandleSize(myHandle);
- if (FSWrite(refNum,&theCount,*myHandle) != noErr) {
- Display(WriteMSG);
- FSClose(refNum);
- HUnlock(myHandle);
- return;
- }
-
- FSClose(refNum);
- }
- HUnlock(myHandle);
- }
-
-
- /* just in case your compiler doesn't already have these...
- otherwise, leave them out... */
-
- strlen(s)
- register char *s;
- {
- char *s0 = s;
-
- while (*s++);
- return (s-s0-1);
- }
-
-
- int toupper(c)
- char c;
- {
- return((c>='a') && (c<='z') ? (c-32) : c);
- }
-
-
- int tolower(c)
- char c;
- {
- return((c>='A') && (c<='Z') ? (c+32) : c);
- }
-
-
- int isupper(c)
- char c;
- {
- return((c>='A') && (c<='Z'));
- }
-
-
- int islower(c)
- char c;
- {
- return((c>='a') && (c<='z'));
- }
-